meteoswiss-mcp 2.2.1 → 2.3.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Data layer for the meteoswissClimateData tool.
3
+ * Fetches homogeneous climate measurement series from NBCN stations.
4
+ */
5
+ import { getLatin1CsvData } from './ogd-data-store.js';
6
+ import { resolveNbcnStation, findNearestNbcnStation } from './ogd-nbcn-stations.js';
7
+ import { parseNumeric } from '../support/ogd-csv-parser.js';
8
+ import { debugData } from '../support/logging.js';
9
+ import { SOURCE_ATTRIBUTION } from '../schemas/ogd-shared.js';
10
+ /**
11
+ * Map resolution names to URL suffixes.
12
+ * Monthly and yearly files contain all history (no _recent suffix).
13
+ * Daily has _recent (last ~2 years) and _historical variants.
14
+ */
15
+ const RESOLUTION_SUFFIX = {
16
+ daily: 'd_recent',
17
+ monthly: 'm',
18
+ yearly: 'y',
19
+ };
20
+ /**
21
+ * Build the download URL for a station's climate data.
22
+ */
23
+ function buildDataUrl(station, resolution) {
24
+ const collection = station.network === 'nbcn-precip' ? 'ogd-nbcn-precip' : 'ogd-nbcn';
25
+ const abbrLower = station.abbr.toLowerCase();
26
+ const suffix = RESOLUTION_SUFFIX[resolution];
27
+ return `https://data.geo.admin.ch/ch.meteoschweiz.${collection}/${abbrLower}/${collection}_${abbrLower}_${suffix}.csv`;
28
+ }
29
+ /**
30
+ * Parse a MeteoSwiss timestamp (DD.MM.YYYY HH:MM) into an ISO-ish YYYY-MM-DD string.
31
+ */
32
+ function parseTimestamp(ts) {
33
+ const match = ts.match(/^(\d{2})\.(\d{2})\.(\d{4})/);
34
+ if (!match)
35
+ return ts;
36
+ return `${match[3]}-${match[2]}-${match[1]}`;
37
+ }
38
+ /**
39
+ * Map CSV columns to structured measurements.
40
+ * Daily, monthly, and yearly CSVs have different column sets.
41
+ */
42
+ function mapMeasurement(row) {
43
+ return {
44
+ date: parseTimestamp(row.reference_timestamp ?? ''),
45
+ // Temperature (available at all resolutions)
46
+ temperature_mean: parseNumeric(row.ths200d0 ?? row.ths200m0 ?? row.ths200y0 ?? null) ?? undefined,
47
+ temperature_max: parseNumeric(row.ths200dx ?? row.ths2dymx ?? row.ths2dyyx ?? null) ?? undefined,
48
+ temperature_min: parseNumeric(row.ths200dn ?? row.ths2dymn ?? row.ths2dyyn ?? null) ?? undefined,
49
+ // Precipitation (monthly/yearly)
50
+ precipitation: parseNumeric(row.rhs150m0 ?? row.rhs150y0 ?? null) ?? undefined,
51
+ // Sunshine (monthly/yearly)
52
+ sunshine_duration_min: parseNumeric(row.shs000m0 ?? row.shs000y0 ?? null) ?? undefined,
53
+ // Radiation (monthly/yearly)
54
+ radiation_w_m2: parseNumeric(row.ghs000m0 ?? row.ghs000y0 ?? null) ?? undefined,
55
+ // Wind (monthly/yearly)
56
+ wind_speed_m_s: parseNumeric(row.fhs010m0 ?? row.fhs010y0 ?? null) ?? undefined,
57
+ // Pressure (monthly/yearly)
58
+ pressure_hpa: parseNumeric(row.phsstam0 ?? row.phsstay0 ?? null) ?? undefined,
59
+ // Day counts (monthly/yearly)
60
+ frost_days: parseNumeric(row.ths00nm0 ?? row.ths00ny0 ?? null) ?? undefined,
61
+ summer_days: parseNumeric(row.ths25xm0 ?? row.ths25xy0 ?? null) ?? undefined,
62
+ heat_days: parseNumeric(row.ths30xm0 ?? row.ths30xy0 ?? null) ?? undefined,
63
+ ice_days: parseNumeric(row.ths00xm0 ?? row.ths00xy0 ?? null) ?? undefined,
64
+ tropical_nights: parseNumeric(row.ths20nm0 ?? row.ths20ny0 ?? null) ?? undefined,
65
+ rain_days: parseNumeric(row.rhs001m0 ?? row.rhs001y0 ?? null) ?? undefined,
66
+ };
67
+ }
68
+ /**
69
+ * Strip undefined values from a measurement to keep the response clean.
70
+ */
71
+ function stripUndefined(m) {
72
+ const result = {};
73
+ for (const [key, value] of Object.entries(m)) {
74
+ if (value !== undefined) {
75
+ result[key] = value;
76
+ }
77
+ }
78
+ return result;
79
+ }
80
+ /**
81
+ * Fetch climate data from MeteoSwiss NBCN stations.
82
+ */
83
+ export async function getClimateData(params) {
84
+ let station;
85
+ let distance_km;
86
+ if (params.coordinates) {
87
+ const result = await findNearestNbcnStation(params.coordinates.lat, params.coordinates.lon);
88
+ station = result.station;
89
+ distance_km = result.distance_km;
90
+ debugData('[ogd-nbcn] Nearest station to coordinates: %s (%.1f km)', station.abbr, distance_km);
91
+ }
92
+ else if (params.station) {
93
+ station = await resolveNbcnStation(params.station);
94
+ debugData('[ogd-nbcn] Resolved station: %s (%s)', station.abbr, station.name);
95
+ }
96
+ else {
97
+ throw new Error('Either "station" or "coordinates" must be provided');
98
+ }
99
+ const resolution = params.resolution ?? 'monthly';
100
+ const url = buildDataUrl(station, resolution);
101
+ const abbrLower = station.abbr.toLowerCase();
102
+ const cacheKey = `climate/${station.network}-${abbrLower}-${RESOLUTION_SUFFIX[resolution]}.csv`;
103
+ const rows = await getLatin1CsvData(url, cacheKey, 'climate');
104
+ debugData('[ogd-nbcn] Fetched %d rows for %s (%s)', rows.length, station.abbr, resolution);
105
+ // Apply date filtering
106
+ let filtered = rows;
107
+ if (params.start_date) {
108
+ const start = params.start_date;
109
+ filtered = filtered.filter((row) => {
110
+ const date = parseTimestamp(row.reference_timestamp ?? '');
111
+ return date >= start;
112
+ });
113
+ }
114
+ if (params.end_date) {
115
+ const end = params.end_date;
116
+ filtered = filtered.filter((row) => {
117
+ const date = parseTimestamp(row.reference_timestamp ?? '');
118
+ return date <= end;
119
+ });
120
+ }
121
+ // Take the most recent rows (from the end), limited by params.limit
122
+ const limit = params.limit ?? 30;
123
+ const sliced = filtered.slice(-limit);
124
+ const data = sliced.map((row) => stripUndefined(mapMeasurement(row)));
125
+ return {
126
+ station: {
127
+ name: station.name,
128
+ abbreviation: station.abbr,
129
+ elevation: station.elevation,
130
+ coordinates: { lat: station.lat, lon: station.lon },
131
+ canton: station.canton,
132
+ distance_km,
133
+ network: station.network,
134
+ },
135
+ resolution,
136
+ data,
137
+ source: SOURCE_ATTRIBUTION,
138
+ };
139
+ }
140
+ //# sourceMappingURL=ogd-climate-data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ogd-climate-data.js","sourceRoot":"","sources":["../../src/data/ogd-climate-data.ts"],"names":[],"mappings":"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"}
@@ -2,13 +2,15 @@
2
2
  * Data layer for the getCurrentWeather tool.
3
3
  * Fetches real-time measurements from the consolidated VQHA80.csv.
4
4
  */
5
- import { getCsvData } from './ogd-data-store.js';
5
+ import { getCsvData, getLatin1CsvData } from './ogd-data-store.js';
6
6
  import { resolveSmnStation, findNearestStation } from './ogd-smn-stations.js';
7
7
  import { parseNumeric } from '../support/ogd-csv-parser.js';
8
8
  import { reverseGeocodeSwiss } from '../support/reverse-geocode.js';
9
9
  import { debugData } from '../support/logging.js';
10
10
  import { SOURCE_ATTRIBUTION } from '../schemas/ogd-shared.js';
11
11
  const REALTIME_CSV_URL = 'https://data.geo.admin.ch/ch.meteoschweiz.messwerte-aktuell/VQHA80.csv';
12
+ /** The 8 stations that have visual observations (OBS) data */
13
+ const OBS_STATIONS = new Set(['ALT', 'BAS', 'CHU', 'GSB', 'JUN', 'SAE', 'SIO', 'SMA']);
12
14
  /** Cache reverse geocode results per station (coordinates are static) */
13
15
  const reverseGeoCache = new Map();
14
16
  async function getCachedReverseGeocode(lat, lon, stationAbbr) {
@@ -57,12 +59,23 @@ export async function getCurrentWeather(params) {
57
59
  getCsvData(REALTIME_CSV_URL, 'measurements/VQHA80.csv', 'realtime', filter),
58
60
  getCachedReverseGeocode(station.lat, station.lon, station.abbr),
59
61
  ]);
60
- if (rows.length === 0) {
61
- throw new Error(`No current data available for station ${station.abbr} (${station.name})`);
62
+ let row = rows[0];
63
+ // Fallback for precipitation-only stations: VQHA80 does not include them
64
+ if (!row && station.network === 'smn-precip') {
65
+ debugData('[ogd-weather] Station %s is precip-only, fetching per-station CSV', station.abbr);
66
+ const abbrLower = station.abbr.toLowerCase();
67
+ const precipUrl = `https://data.geo.admin.ch/ch.meteoschweiz.ogd-smn-precip/${abbrLower}/ogd-smn-precip_${abbrLower}_t_recent.csv`;
68
+ const precipRows = await getCsvData(precipUrl, `measurements/smn-precip-${abbrLower}-t-recent.csv`, 'realtime');
69
+ // Use the most recent row (last in the CSV)
70
+ row = precipRows.length > 0 ? precipRows[precipRows.length - 1] : undefined;
62
71
  }
63
- const row = rows[0];
64
72
  if (!row) {
65
- throw new Error(`No data row for station ${station.abbr}`);
73
+ throw new Error(`No current data available for station ${station.abbr} (${station.name})`);
74
+ }
75
+ // Enrich with visual observations for the 8 OBS stations
76
+ let visual_observations;
77
+ if (OBS_STATIONS.has(station.abbr)) {
78
+ visual_observations = await fetchVisualObservations(station.abbr);
66
79
  }
67
80
  return {
68
81
  station: {
@@ -73,8 +86,9 @@ export async function getCurrentWeather(params) {
73
86
  municipality: geo?.municipality,
74
87
  canton: geo?.canton ?? station.canton,
75
88
  distance_km,
89
+ network: station.network,
76
90
  },
77
- timestamp: row.Date ?? '',
91
+ timestamp: row.Date ?? row.reference_timestamp ?? '',
78
92
  measurements: {
79
93
  temperature: measurement(row, 'tre200s0', '\u00B0C'),
80
94
  humidity: measurement(row, 'ure200s0', '%'),
@@ -89,7 +103,51 @@ export async function getCurrentWeather(params) {
89
103
  pressure_sea_level: measurement(row, 'pp0qffs0', 'hPa'),
90
104
  snow_depth: measurement(row, 'htoauts0', 'cm'),
91
105
  },
106
+ visual_observations,
92
107
  source: SOURCE_ATTRIBUTION,
93
108
  };
94
109
  }
110
+ /**
111
+ * Fetch the latest visual observation for an OBS station.
112
+ * Returns undefined if the fetch fails (non-critical enrichment).
113
+ */
114
+ async function fetchVisualObservations(abbr) {
115
+ try {
116
+ const abbrLower = abbr.toLowerCase();
117
+ const url = `https://data.geo.admin.ch/ch.meteoschweiz.ogd-obs/${abbrLower}/ogd-obs_${abbrLower}_d_recent.csv`;
118
+ const rows = await getLatin1CsvData(url, `observations/obs-${abbrLower}-d-recent.csv`, 'realtime');
119
+ if (rows.length === 0)
120
+ return undefined;
121
+ const latestRow = rows[rows.length - 1];
122
+ const cloudCover = parseNumeric(latestRow.nto000d0 ?? null);
123
+ // MeteoSwiss CSV uses '-' for "phenomenon not observed", which the CSV parser
124
+ // maps to null. For boolean observation flags, not-observed means false.
125
+ const parseFlag = (val) => {
126
+ if (val === null)
127
+ return false;
128
+ const num = parseNumeric(val);
129
+ return num === 1;
130
+ };
131
+ // Parse timestamp DD.MM.YYYY → YYYY-MM-DD
132
+ const ts = latestRow.reference_timestamp ?? '';
133
+ const match = ts.match(/^(\d{2})\.(\d{2})\.(\d{4})/);
134
+ const date = match ? `${match[3]}-${match[2]}-${match[1]}` : ts;
135
+ return {
136
+ date,
137
+ cloud_cover_percent: cloudCover ?? undefined,
138
+ is_clear_day: parseFlag(latestRow.nto002d0 ?? null),
139
+ is_overcast_day: parseFlag(latestRow.nto008d0 ?? null),
140
+ has_rain: parseFlag(latestRow.w1p012d0 ?? null),
141
+ has_rain_and_snow: parseFlag(latestRow.w2p001d0 ?? null),
142
+ has_snowfall: parseFlag(latestRow.w2p002d0 ?? null),
143
+ has_hail: parseFlag(latestRow.w3p002d0 ?? null),
144
+ has_fog: parseFlag(latestRow.w5p002d0 ?? null),
145
+ has_snow_coverage: parseFlag(latestRow.est000d0 ?? null),
146
+ };
147
+ }
148
+ catch (error) {
149
+ debugData('[ogd-weather] Failed to fetch visual observations for %s: %O', abbr, error);
150
+ return undefined;
151
+ }
152
+ }
95
153
  //# sourceMappingURL=ogd-current-weather.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ogd-current-weather.js","sourceRoot":"","sources":["../../src/data/ogd-current-weather.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ogd-current-weather.js","sourceRoot":"","sources":["../../src/data/ogd-current-weather.ts"],"names":[],"mappings":"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"}
@@ -21,14 +21,40 @@ function resolveFixturePath(url) {
21
21
  // Map known URL patterns to fixture directories
22
22
  if (url.includes('VQHA80.csv'))
23
23
  return path.join(OGD_FIXTURES_ROOT, 'measurements', 'VQHA80.csv');
24
- if (url.includes('meta_stations.csv'))
24
+ // SMN-precip metadata and data (must come BEFORE SMN to avoid 'smn' substring match)
25
+ if (url.includes('meta_stations.csv') && url.includes('smn-precip'))
26
+ return path.join(OGD_FIXTURES_ROOT, 'metadata', 'ogd-smn-precip_meta_stations.csv');
27
+ if (url.includes('ogd-smn-precip') && url.includes('_t_recent.csv'))
28
+ return path.join(OGD_FIXTURES_ROOT, 'measurements', 'smn-precip-abe-t-recent.csv');
29
+ // SMN (weather station) metadata
30
+ if (url.includes('meta_stations.csv') && url.includes('smn'))
25
31
  return path.join(OGD_FIXTURES_ROOT, 'metadata', 'ogd-smn_meta_stations.csv');
32
+ if (url.includes('meta_parameters.csv') && url.includes('smn'))
33
+ return path.join(OGD_FIXTURES_ROOT, 'metadata', 'ogd-smn_meta_parameters.csv');
34
+ // NBCN metadata and data (nbcn-precip must come BEFORE nbcn)
35
+ if (url.includes('meta_stations.csv') && url.includes('nbcn-precip'))
36
+ return path.join(OGD_FIXTURES_ROOT, 'metadata', 'ogd-nbcn-precip_meta_stations.csv');
37
+ if (url.includes('meta_stations.csv') && url.includes('nbcn'))
38
+ return path.join(OGD_FIXTURES_ROOT, 'metadata', 'ogd-nbcn_meta_stations.csv');
39
+ if (url.includes('ogd-nbcn') && url.includes('_m.csv'))
40
+ return path.join(OGD_FIXTURES_ROOT, 'climate', 'nbcn-bas-m.csv');
41
+ if (url.includes('ogd-nbcn') && url.includes('_d_recent.csv'))
42
+ return path.join(OGD_FIXTURES_ROOT, 'climate', 'nbcn-bas-d-recent.csv');
43
+ // OBS (visual observations) data
44
+ if (url.includes('ogd-obs') && url.includes('_d_recent.csv'))
45
+ return path.join(OGD_FIXTURES_ROOT, 'observations', 'obs-sma-d-recent.csv');
46
+ // Pollen metadata and data
47
+ if (url.includes('meta_stations.csv') && url.includes('pollen'))
48
+ return path.join(OGD_FIXTURES_ROOT, 'metadata', 'ogd-pollen_meta_stations.csv');
49
+ if (url.includes('meta_parameters.csv') && url.includes('pollen'))
50
+ return path.join(OGD_FIXTURES_ROOT, 'metadata', 'ogd-pollen_meta_parameters.csv');
51
+ if (url.includes('ogd-pollen') && url.includes('_d_recent.csv'))
52
+ return path.join(OGD_FIXTURES_ROOT, 'pollen', 'pzh-daily-recent.csv');
53
+ // Forecast metadata
26
54
  if (url.includes('meta_point.csv'))
27
55
  return path.join(OGD_FIXTURES_ROOT, 'metadata', 'ogd-local-forecasting_meta_point.csv');
28
56
  if (url.includes('meta_parameters.csv') && url.includes('forecasting'))
29
57
  return path.join(OGD_FIXTURES_ROOT, 'metadata', 'ogd-local-forecasting_meta_parameters.csv');
30
- if (url.includes('meta_parameters.csv') && url.includes('smn'))
31
- return path.join(OGD_FIXTURES_ROOT, 'metadata', 'ogd-smn_meta_parameters.csv');
32
58
  // Forecast CSVs: match by parameter name
33
59
  for (const param of [
34
60
  'tre200dx',
@@ -1 +1 @@
1
- {"version":3,"file":"ogd-data-store.js","sourceRoot":"","sources":["../../src/data/ogd-data-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ogd-data-store.js","sourceRoot":"","sources":["../../src/data/ogd-data-store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,QAAQ,EAAe,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEnF,MAAM,cAAc,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAC;AAEjD;;;GAGG;AACH,SAAS,kBAAkB,CAAC,GAAW;IACrC,IAAI,CAAC,iBAAiB;QAAE,OAAO,IAAI,CAAC;IAEpC,gDAAgD;IAChD,IAAI,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;IAElG,qFAAqF;IACrF,IAAI,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC;QACjE,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,UAAU,EAAE,kCAAkC,CAAC,CAAC;IACtF,IAAI,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC;QACjE,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,cAAc,EAAE,6BAA6B,CAAC,CAAC;IAErF,iCAAiC;IACjC,IAAI,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;QAC1D,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,UAAU,EAAE,2BAA2B,CAAC,CAAC;IAC/E,IAAI,GAAG,CAAC,QAAQ,CAAC,qBAAqB,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;QAC5D,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,UAAU,EAAE,6BAA6B,CAAC,CAAC;IAEjF,6DAA6D;IAC7D,IAAI,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC;QAClE,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,UAAU,EAAE,mCAAmC,CAAC,CAAC;IACvF,IAAI,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC3D,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,UAAU,EAAE,4BAA4B,CAAC,CAAC;IAChF,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACpD,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC;IACnE,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC;QAC3D,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,SAAS,EAAE,uBAAuB,CAAC,CAAC;IAE1E,iCAAiC;IACjC,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC;QAC1D,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,cAAc,EAAE,sBAAsB,CAAC,CAAC;IAE9E,2BAA2B;IAC3B,IAAI,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC7D,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,UAAU,EAAE,8BAA8B,CAAC,CAAC;IAClF,IAAI,GAAG,CAAC,QAAQ,CAAC,qBAAqB,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC/D,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,UAAU,EAAE,gCAAgC,CAAC,CAAC;IACpF,IAAI,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC;QAC7D,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,QAAQ,EAAE,sBAAsB,CAAC,CAAC;IAExE,oBAAoB;IACpB,IAAI,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QAChC,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,UAAU,EAAE,sCAAsC,CAAC,CAAC;IAC1F,IAAI,GAAG,CAAC,QAAQ,CAAC,qBAAqB,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC;QACpE,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,UAAU,EAAE,2CAA2C,CAAC,CAAC;IAE/F,yCAAyC;IACzC,KAAK,MAAM,KAAK,IAAI;QAClB,UAAU;QACV,UAAU;QACV,UAAU;QACV,UAAU;QACV,UAAU;QACV,UAAU;QACV,UAAU;KACX,EAAE,CAAC;QACF,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,CAAC;YAC/B,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,WAAW,EAAE,GAAG,KAAK,MAAM,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,SAAS,SAAS,CAAC,IAAY,EAAE,QAAgB;IAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,QAAQ,CAAC;IACjC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;AAClD,CAAC;AAED,iCAAiC;AACjC,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,QAAQ,EAAE,SAAS,CAAC,wBAAwB,EAAE,MAAM,CAAC;IACrD,QAAQ,EAAE,SAAS,CAAC,wBAAwB,EAAE,SAAS,CAAC;IACxD,QAAQ,EAAE,SAAS,CAAC,wBAAwB,EAAE,UAAU,CAAC;IACzD,OAAO,EAAE,SAAS,CAAC,uBAAuB,EAAE,WAAW,CAAC;CAChD,CAAC;AAIX,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC;AAExF;;GAEG;AACH,KAAK,UAAU,gBAAgB,CAAC,SAAiB,EAAE,IAAqB;IACtE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACpC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,GAAG,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC;IACjD,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAClC,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;AACtC,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,aAAa,CAAC,SAAiB,EAAE,GAAW;IACzD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QACtC,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;YACd,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,aAAa;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,GAAW,EACX,QAAgB,EAChB,IAAe,EACf,MAAiC;IAEjC,yDAAyD;IACzD,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAC5C,IAAI,WAAW,EAAE,CAAC;QAChB,SAAS,CAAC,+BAA+B,EAAE,WAAW,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACrD,OAAO,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAChC,CAAC;IACD,IAAI,iBAAiB,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,wCAAwC,CAAC,CAAC;IAC3F,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAE5B,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IACnD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,SAAS,CAAC,8BAA8B,EAAE,QAAQ,CAAC,CAAC;QACpD,OAAO,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,CAAC;IAED,SAAS,CAAC,4BAA4B,EAAE,GAAG,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7E,MAAM,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACxC,SAAS,CAAC,mCAAmC,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACtE,OAAO,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAChC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAW,EACX,QAAgB,EAChB,IAAe,EACf,MAAiC;IAEjC,yDAAyD;IACzD,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAC5C,IAAI,WAAW,EAAE,CAAC;QAChB,SAAS,CAAC,+BAA+B,EAAE,WAAW,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACrD,OAAO,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAChC,CAAC;IACD,IAAI,iBAAiB,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,wCAAwC,CAAC,CAAC;IAC3F,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAE5B,sCAAsC;IACtC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IACnD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,SAAS,CAAC,8BAA8B,EAAE,QAAQ,CAAC,CAAC;QACpD,OAAO,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,CAAC;IAED,SAAS,CAAC,4CAA4C,EAAE,GAAG,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3D,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACxC,SAAS,CAAC,6CAA6C,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAChF,OAAO,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Station metadata loader for MeteoSwiss NBCN (National Basic Climatic Network) stations.
3
+ * Loads and caches station metadata from the OGD STAC API.
4
+ * Merges NBCN (29 climate stations) and NBCN-precip (46 precipitation stations).
5
+ */
6
+ import { getCollection } from './ogd-stac-client.js';
7
+ import { getLatin1CsvData } from './ogd-data-store.js';
8
+ import { parseNumeric } from '../support/ogd-csv-parser.js';
9
+ import { normalize } from '../support/normalize.js';
10
+ import { scoreNameMatch } from '../support/name-matcher.js';
11
+ import { findNearest } from '../support/haversine.js';
12
+ import { geocodeSwissLocation } from '../support/geocode.js';
13
+ import { debugData } from '../support/logging.js';
14
+ import { OGD_COLLECTIONS } from '../schemas/ogd-shared.js';
15
+ /** Max distance (km) for geocoding fallback — NBCN is sparser than SMN */
16
+ const MAX_GEOCODE_DISTANCE_KM = 80;
17
+ let stationCache = null;
18
+ let stationByAbbr = null;
19
+ /**
20
+ * Parse station metadata rows into NbcnStation objects.
21
+ */
22
+ function parseStationRows(rows, network) {
23
+ return rows
24
+ .filter((r) => r.station_abbr)
25
+ .map((row) => ({
26
+ abbr: row.station_abbr ?? '',
27
+ name: row.station_name ?? '',
28
+ canton: row.station_canton ?? '',
29
+ elevation: parseNumeric(row.station_height_masl ?? null) ?? 0,
30
+ lat: parseNumeric(row.station_coordinates_wgs84_lat ?? null) ?? 0,
31
+ lon: parseNumeric(row.station_coordinates_wgs84_lon ?? null) ?? 0,
32
+ data_since: row.station_data_since ?? '',
33
+ network,
34
+ }));
35
+ }
36
+ /**
37
+ * Load NBCN + NBCN-precip station metadata from the OGD STAC API.
38
+ * Cached in memory after first load.
39
+ *
40
+ * @returns Array of all NBCN and NBCN-precip stations
41
+ */
42
+ export async function loadNbcnStations() {
43
+ if (stationCache)
44
+ return stationCache;
45
+ debugData('[ogd-nbcn] Loading station metadata (NBCN + NBCN-precip)...');
46
+ const [nbcnCollection, precipCollection] = await Promise.all([
47
+ getCollection(OGD_COLLECTIONS.NBCN),
48
+ getCollection(OGD_COLLECTIONS.NBCN_PRECIP),
49
+ ]);
50
+ const nbcnAsset = nbcnCollection.assets?.['ogd-nbcn_meta_stations.csv'];
51
+ if (!nbcnAsset) {
52
+ throw new Error('Station metadata asset not found in NBCN collection');
53
+ }
54
+ const precipAsset = precipCollection.assets?.['ogd-nbcn-precip_meta_stations.csv'];
55
+ if (!precipAsset) {
56
+ throw new Error('Station metadata asset not found in NBCN-precip collection');
57
+ }
58
+ const [nbcnRows, precipRows] = await Promise.all([
59
+ getLatin1CsvData(nbcnAsset.href, 'metadata/nbcn-stations.csv', 'metadata'),
60
+ getLatin1CsvData(precipAsset.href, 'metadata/nbcn-precip-stations.csv', 'metadata'),
61
+ ]);
62
+ const nbcnStations = parseStationRows(nbcnRows, 'nbcn');
63
+ const precipStations = parseStationRows(precipRows, 'nbcn-precip');
64
+ stationCache = [...nbcnStations, ...precipStations];
65
+ stationByAbbr = new Map(stationCache.map((s) => [s.abbr.toLowerCase(), s]));
66
+ debugData('[ogd-nbcn] Loaded %d stations (%d NBCN + %d precip)', stationCache.length, nbcnStations.length, precipStations.length);
67
+ return stationCache;
68
+ }
69
+ /**
70
+ * Find the nearest NBCN station to a given WGS84 coordinate.
71
+ */
72
+ export async function findNearestNbcnStation(lat, lon) {
73
+ const stations = await loadNbcnStations();
74
+ const result = findNearest(stations, (s) => s.lat, (s) => s.lon, lat, lon);
75
+ if (!result) {
76
+ throw new Error('No NBCN stations available');
77
+ }
78
+ return { station: result.item, distance_km: result.distance_km };
79
+ }
80
+ /**
81
+ * Resolve a query to an NBCN station.
82
+ * Tries: exact abbreviation → fuzzy name → geocoding fallback.
83
+ */
84
+ export async function resolveNbcnStation(query) {
85
+ const stations = await loadNbcnStations();
86
+ if (!stationByAbbr) {
87
+ throw new Error('NBCN station index not initialized');
88
+ }
89
+ const q = normalize(query.trim());
90
+ if (q === '') {
91
+ throw new Error('Station query must not be empty. Provide a station name (e.g., "Zurich"), ' +
92
+ 'abbreviation (e.g., "SMA"), or address (e.g., "Bahnhofplatz 1 Bern").');
93
+ }
94
+ const exact = stationByAbbr.get(q);
95
+ if (exact)
96
+ return exact;
97
+ // Scored name match — word-boundary matches beat substring matches
98
+ let bestStation;
99
+ let bestScore = 0;
100
+ for (const s of stations) {
101
+ const score = scoreNameMatch(q, normalize(s.name));
102
+ if (score > bestScore ||
103
+ (score === bestScore && bestStation && s.name.length < bestStation.name.length)) {
104
+ bestScore = score;
105
+ bestStation = s;
106
+ }
107
+ }
108
+ if (bestStation)
109
+ return bestStation;
110
+ debugData('[ogd-nbcn] No direct match for "%s", trying geocoding...', query);
111
+ const geocoded = await geocodeSwissLocation(query);
112
+ if (geocoded) {
113
+ const { station, distance_km } = await findNearestNbcnStation(geocoded.lat, geocoded.lon);
114
+ if (distance_km > MAX_GEOCODE_DISTANCE_KM) {
115
+ debugData('[ogd-nbcn] Geocoded "%s" too far from nearest station: %.1f km (limit: %d km)', query, distance_km, MAX_GEOCODE_DISTANCE_KM);
116
+ }
117
+ else {
118
+ debugData('[ogd-nbcn] Geocoded "%s" → %s, nearest station: %s (%s, %.1f km)', query, geocoded.name, station.abbr, station.name, distance_km);
119
+ return station;
120
+ }
121
+ }
122
+ const examples = stations
123
+ .filter((s) => s.network === 'nbcn')
124
+ .slice(0, 5)
125
+ .map((s) => `${s.abbr} (${s.name})`)
126
+ .join(', ');
127
+ throw new Error(`No climate station found for "${query}". ` +
128
+ `Try a Swiss location name, station abbreviation, or address. Examples: ${examples}`);
129
+ }
130
+ /**
131
+ * Clear the in-memory station cache. Useful for testing.
132
+ */
133
+ export function clearNbcnStationCache() {
134
+ stationCache = null;
135
+ stationByAbbr = null;
136
+ }
137
+ //# sourceMappingURL=ogd-nbcn-stations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ogd-nbcn-stations.js","sourceRoot":"","sources":["../../src/data/ogd-nbcn-stations.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,31 @@ import { parseNumeric } from '../support/ogd-csv-parser.js';
8
8
  import { normalize } from '../support/normalize.js';
9
9
  import { debugData } from '../support/logging.js';
10
10
  import { OGD_COLLECTIONS, SOURCE_ATTRIBUTION } from '../schemas/ogd-shared.js';
11
+ /**
12
+ * Map from the first 6 characters of a pollen parameter code to a short
13
+ * species display name. MeteoSwiss codes follow the pattern:
14
+ * k{a|h}{genus-4-chars}{resolution} where genus is a Latin-genus abbreviation.
15
+ */
16
+ const POLLEN_SPECIES = {
17
+ kaalnu: 'Alder (Alnus)',
18
+ kabetu: 'Birch (Betula)',
19
+ kacory: 'Hazel (Corylus)',
20
+ kafagu: 'Beech (Fagus)',
21
+ kafrax: 'Ash (Fraxinus)',
22
+ kaquer: 'Oak (Quercus)',
23
+ khpoac: 'Grasses (Poaceae)',
24
+ };
25
+ /**
26
+ * Get a short display name for a pollen parameter code.
27
+ * Falls back to the raw code if the prefix is not recognized.
28
+ *
29
+ * @param code - Parameter shortname (or 6-char prefix) like 'kaalnud1'
30
+ * @returns Short species name like 'Alder (Alnus)', or the raw code
31
+ */
32
+ function pollenDisplayName(code) {
33
+ const prefix = code.slice(0, 6);
34
+ return POLLEN_SPECIES[prefix] ?? code;
35
+ }
11
36
  /**
12
37
  * Fetch pollen data from MeteoSwiss OGD.
13
38
  *
@@ -23,18 +48,6 @@ export async function getPollenData(params) {
23
48
  throw new Error('Pollen station metadata asset not found');
24
49
  }
25
50
  const stationRows = await getLatin1CsvData(stationMetaAsset.href, 'metadata/pollen-stations.csv', 'metadata');
26
- // Get parameter metadata for pollen type names
27
- const paramMetaAsset = collection.assets?.['ogd-pollen_meta_parameters.csv'];
28
- const paramRows = paramMetaAsset
29
- ? await getLatin1CsvData(paramMetaAsset.href, 'metadata/pollen-parameters.csv', 'metadata')
30
- : [];
31
- const paramNames = new Map();
32
- for (const row of paramRows) {
33
- const code = row.parameter_shortname ?? '';
34
- const name = row.parameter_description_en ?? row.parameter_description_de ?? code;
35
- if (code)
36
- paramNames.set(code, name);
37
- }
38
51
  // Filter stations if search provided
39
52
  let filteredStations = stationRows.filter((r) => r.station_abbr);
40
53
  if (params.station) {
@@ -58,16 +71,34 @@ export async function getPollenData(params) {
58
71
  const latestRow = rows[rows.length - 1];
59
72
  if (!latestRow)
60
73
  return null;
61
- const pollen = [];
74
+ // Collect measurements, preferring d1 (calendar day 0-0 UTC) over d0 (6-6 UTC)
75
+ const d0Values = new Map();
76
+ const d1Values = new Map();
62
77
  for (const [key, value] of Object.entries(latestRow)) {
63
78
  if (key === 'station_abbr' || key === 'reference_timestamp' || key === 'Date')
64
79
  continue;
65
80
  const numVal = parseNumeric(value);
66
81
  if (numVal === null)
67
82
  continue;
83
+ const prefix = key.slice(0, 6);
84
+ const suffix = key.slice(6);
85
+ if (suffix === 'd1') {
86
+ d1Values.set(prefix, numVal);
87
+ }
88
+ else if (suffix === 'd0') {
89
+ d0Values.set(prefix, numVal);
90
+ }
91
+ // Ignore h0, y0, and other resolutions for daily pollen output
92
+ }
93
+ const pollen = [];
94
+ const allPrefixes = new Set([...d1Values.keys(), ...d0Values.keys()]);
95
+ for (const prefix of allPrefixes) {
96
+ const value = d1Values.get(prefix) ?? d0Values.get(prefix);
97
+ if (value === undefined)
98
+ continue;
68
99
  pollen.push({
69
- type: paramNames.get(key) ?? key,
70
- value: numVal,
100
+ type: pollenDisplayName(prefix),
101
+ value,
71
102
  unit: 'particles/m\u00B3',
72
103
  });
73
104
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ogd-pollen-data.js","sourceRoot":"","sources":["../../src/data/ogd-pollen-data.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ogd-pollen-data.js","sourceRoot":"","sources":["../../src/data/ogd-pollen-data.ts"],"names":[],"mappings":"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"}