SwiftIGRF is a Swift package for evaluating any generation of the International Geomagnetic Reference Field (IGRF) geomagnetic field model. This project was inspired by the NCEI IGRF Python package.
SwiftIGRF provides a command-line interface (CLI) tool that allows calculation of the seven main geomagnetic field components (Declination, Inclination, Total Field, Horizontal, North, East and Vertical strength, or D, I, F, H, X, Y, Z) and their respective secular variation for a given latitude, longitude, altitude, and time.
You can specify any IGRF generation from 1 to 14 (as of November 2024).
The project is structured with a clear separation between:
- Core calculation code (independent library)
- CLI application
- iOS sample application demonstrating how to use the core library
The code accepts geodetic coordinates (WGS-84) with altitude in km above the WGS-84 ellipsoid or geocentric coordinates with radius in km from Earth's center (6371.2 km is the nominal geophysical surface radius).
Location values can be entered in decimal degrees or degrees and minutes.
There are no validity checks on the models, so be aware of errors caused by extrapolation outside the valid range.
Check NCEI IGRF for validity ranges on each generation as these vary widely. For example:
- IGRF-1 is valid from January 1, 1965 to December 31, 1979
- IGRF-13 is valid from January 1, 1900 to December 31, 2024
- IGRF-14 is valid from January 1, 1900 to December 31, 2029
SwiftIGRF supports the following Apple platforms:
- iOS 17.0+
- macOS 14.0+
- tvOS 17.0+
- watchOS 8.0+
To use SwiftIGRF as a command-line tool:
- Clone the repository
- Build the project:
swift build
- Run the IGRF command:
.build/debug/igrf
- Follow the prompts to input your data
Here's an example of checking geomagnetic data for Shibuya Station in Tokyo, Japan (latitude 35° 39.48', longitude 139° 42.096') for the year 2025, with output to a file:
Input example
******************************************************
* IGRF SYNTHESIS PROGRAM *
* *
* A program for the computation of geomagnetic *
* field elements from the International Geomagnetic *
* Reference Field (14th generation) as revised in *
* December 2024 by the IAGA Working Group V-MOD. *
* *
* It is valid for dates from 1900.0 to 2030.0; *
* values up to 2035.0 will be computed with *
* reduced accuracy. Values for dates before 1945.0 *
* and after 2020.0 are non-definitive, otherwise *
* the values are definitive. *
* *
* *
* (on behalf of) IAGA Working Group V-MOD *
******************************************************
Enter number of require IGRF generation (1 to 14)
or press "Return" for IGRF-14
Enter generation number:
14
Loading IGRF coefficient file: /Users/satoutakeshi/local_product/Personal-Factory/flying-star-fengshui/SwiftIGRF/SHC_files/IGRF14.SHC
Successfully loaded IGRF-14 coefficients
Enter name of output file
or press 'Return' for output to screen
Enter filename: output.txt
output.txt
Choose an option:
1 - values at one location and date
2 - values at yearly intervals at one location
3 - values on a latitude/longitude grid at one date
->1
Enter format of latitudes and longitudes:
1 - in degrees & minutes
2 - in decimal degrees
->1
Enter value for coordinate system:
1 - geodetic (shape of Earth using the WGS-84 ellipsoid)
2 - geocentric (shape of Earth is approximated by a sphere)
->1
Enter latitude & longitude in degrees & minutes
(if either latitude or longitude is between -1
and 0 degrees, enter the minutes as negative).
Enter integers for degrees, floats for the minutes if needed
->35 39.48 139 42.096
Enter altitude in km:
->0
Enter decimal date in years 1900-2030:
->2025
Written to file: output.txtWhen you run the command with the options shown above, it will generate output similar to the following:
Sample for output file
Geomagnetic field values at: 35.6580° / 139.7016°, at altitude 0.0 for 2025.0 using IGRF-14
Declination (D): -7.855°
Inclination (I): 49.485°
Horizontal intensity (H): 30411.0 nT
Total intensity (F) : 46811.4 nT
North component (X) : 30125.7 nT
East component (Y) : -4156.1 nT
Vertical component (Z) : 35587.6 nT
Declination SV (D): -2.40 arcmin/yr
Inclination SV (I): 1.26 arcmin/yr
Horizontal SV (H): 6.4 nT/yr
Total SV (F) : 29.9 nT/yr
North SV (X) : 3.4 nT/yr
East SV (Y) : -21.9 nT/yr
Vertical SV (Z) : 33.9 nT/yrTo use this package in your Swift project, add it as a dependency in your Package.swift file:
// Package.swift
dependencies: [
.package(url: "https://github.com/yourusername/SwiftIGRF.git", from: "0.0.3")
],
targets: [
.target(
name: "YourApp",
dependencies: [
.product(name: "IGRFClient", package: "SwiftIGRF"),
.product(name: "IGRFCore", package: "SwiftIGRF"),
],
)
]For more details, please check the Examples folder.
Here's an example of calculating the magnetic field for Tokyo's coordinates:
import IGRFClient
let result = try IGRFClient.create(igrfGen: .igrf14)
.set(system: .geodetic)
.set(
inputLocation: .decimalDegrees(latitude: 35.6762, longitude: 139.6503)
)
.set(alt: 0)
.set(date: Date())
.synthesize()You can get the calculation results as follows:
Text("Declination (D): \(String(format: " %.3f", result.result.geoComponents.declination))°")
Text("Inclination (I): \(String(format: " %.3f", result.result.geoComponents.inclination))°")
Text("Horizontal intensity (H): \(String(format: " %.1f", result.result.geoComponents.horizontalIntensity)) nT")
Text("Total intensity (F): \(String(format: " %.1f", result.result.geoComponents.effectiveField)) nT")
Text("North component (X): \(String(format: " %.1f", result.result.cartesianComps.x)) nT")
Text("East component (Y): \(String(format: " %.1f", result.result.cartesianComps.y)) nT")
Text("Vertical component (Z): \(String(format: " %.1f", result.result.cartesianComps.z)) nT")
Text("Declination SV (D): \(String(format: " %.2f", result.result.geoComponentsSV.declination)) arcmin/yr")
Text("Inclination SV (I): \(String(format: " %.2f", result.result.geoComponentsSV.inclination)) arcmin/yr")
Text("Horizontal SV (H): \(String(format: " %.1f", result.result.geoComponentsSV.horizontalIntensity)) nT/yr")
Text("Total SV (F): \(String(format: " %.1f", result.result.geoComponentsSV.effectiveField)) nT/yr")
Text("North SV (X): \(String(format: " %.1f", result.result.cartesianCompsSV.x)) nT/yr")
Text("East SV (Y): \(String(format: " %.1f", result.result.cartesianCompsSV.y)) nT/yr")
Text("Vertical SV (Z): \(String(format: " %.1f", result.result.cartesianCompsSV.z)) nT/yr")Currently, the MagneticFieldSynthesizer is available for use, but the following features are not yet implemented:
HistoricalMagneticFieldSynthesizer(option 2) for calculating values at a single location over multiple yearsSpatialMagneticFieldSynthesizer(option 3) for calculating values on a latitude/longitude grid at a single point in time
- Implement
HistoricalMagneticFieldSynthesizer - Implement
SpatialMagneticFieldSynthesizer - Enhance documentation
- Add more tests -[x] Expand iOS sample application
This project is released under the MIT License. See the LICENSE file for details.