- {status === 'loading' ?
+ {lightningStatus === 'loading' ?
: null}
- {status === 'error' ?
+ {lightningStatus === 'error' ?
An error occurred while fetching lightning data. : null}
- {status === 'idle' && lightningInfo.length === 0 ?
+ {lightningStatus === 'idle' && lightningInfo.length === 0 ?
No lightning records found.
: null}
@@ -581,30 +673,72 @@ const ESRIMap: EventWidget.IWidget = {
}
}
+/** Replaces map-setting placeholders with values from fault information. */
function resolveVars(str: string, faultInfo: IFaultInfo[]): string {
+ let result = str;
+ for (const info of faultInfo) {
+ if (info.Value != null)
+ result = result.split(`{${info.Key}}`).join(info.Value.toString());
+ }
- const vars = {
+ const aliases = {
'time': '',
'station': '',
'line': '',
+ 'distance': ''
};
if (faultInfo.length > 0) {
- const t = moment(faultInfo[0]?.Inception);
- vars["time"] = t.utc().format('YYYY-MM-DDTHH') + ':' + (t.minutes() - t.minutes() % 5).toString();
- vars["station"] = faultInfo[0]?.StationName.toUpperCase();
- vars["line"] = faultInfo[0]?.AssetName.toUpperCase();
- }
+ const t = moment(getFaultInfoValue(faultInfo, 'FaultTime'));
+ if (t.isValid())
+ aliases["time"] = t.utc().format('YYYY-MM-DDTHH') + ':' + (t.minutes() - t.minutes() % 5).toString();
- let result = str;
- for (const key in vars) {
- if (str.includes(`\{${key}\}`))
- result = result.replace(`\{${key}\}`, vars[key]);
+ aliases["station"] = getFaultInfoValue(faultInfo, 'StationID').toUpperCase();
+ aliases["line"] = getFaultInfoValue(faultInfo, 'LineAssetKey').toUpperCase();
+ aliases["distance"] = getFaultInfoValue(faultInfo, 'FaultDistance');
}
+
+ for (const key in aliases)
+ result = result.split(`{${key}}`).join(aliases[key]);
+
return result;
}
+/** Returns a fault-information value as text. */
+function getFaultInfoValue(faultInfo: IFaultInfo[], key: string): string {
+ const value = faultInfo.find(info => info.Key === key)?.Value;
+ return value == null ? '' : value.toString();
+}
+
+/** Parses the first valid latitude and longitude from a structure crawler HTML/CSV response. */
+function parseStructureLocation(response: string): IStructureLocation | null {
+ const document = new DOMParser().parseFromString(response, 'text/html');
+ const csv = document.body.textContent?.trim() ?? '';
+ const lines = csv.split(/[\r\n]+/).map(line => line.trim()).filter(line => line.length > 0);
+
+ if (lines.length < 2)
+ return null;
+
+ const fields = lines[0].split(',').map(field => field.trim());
+ const latitudeIndex = fields.findIndex(field => field.toLowerCase() === 'latitude');
+ const longitudeIndex = fields.findIndex(field => field.toLowerCase() === 'longitude');
+
+ if (latitudeIndex === -1 || longitudeIndex === -1)
+ return null;
+
+ for (const line of lines.slice(1)) {
+ const values = line.split(',').map(value => value.trim());
+ const latitude = parseFloat(values[latitudeIndex]);
+ const longitude = parseFloat(values[longitudeIndex]);
+
+ if (Number.isFinite(latitude) && Number.isFinite(longitude))
+ return { Latitude: latitude, Longitude: longitude };
+ }
+
+ return null;
+}
+
const LayerSettings = (props: { Layer: ILayerSetting, SetLayer: (layer: ILayerSetting | undefined) => void, Index: number }) => {
return <>